package com.cjd.common.utils

import android.content.Context
import android.media.MediaScannerConnection
import android.net.Uri
import android.text.TextUtils
import java.io.File

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/10/11
 * description
 */
object MediaUtil {
    private val MIME_ARRAY = arrayOf(
        arrayOf(".3gp", "video/3gpp"),
        arrayOf(".apk", "application/vnd.android.package-archive"),
        arrayOf(".asf", "video/x-ms-asf"),
        arrayOf(".avi", "video/x-msvideo"),
        arrayOf(".bin", "application/octet-stream"),
        arrayOf(".bmp", "image/bmp"),
        arrayOf(".c", "text/plain"),
        arrayOf(".class", "application/octet-stream"),
        arrayOf(".conf", "text/plain"),
        arrayOf(".cpp", "text/plain"),
        arrayOf(".doc", "application/msword"),
        arrayOf(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
        arrayOf(".xls", "application/vnd.ms-excel"),
        arrayOf(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
        arrayOf(".exe", "application/octet-stream"),
        arrayOf(".gif", "image/gif"),
        arrayOf(".gtar", "application/x-gtar"),
        arrayOf(".gz", "application/x-gzip"),
        arrayOf(".h", "text/plain"),
        arrayOf(".htm", "text/html"),
        arrayOf(".html", "text/html"),
        arrayOf(".jar", "application/java-archive"),
        arrayOf(".java", "text/plain"),
        arrayOf(".jpeg", "image/jpeg"),
        arrayOf(".jpg", "image/jpeg"),
        arrayOf(".js", "application/x-JavaScript"),
        arrayOf(".log", "text/plain"),
        arrayOf(".m3u", "audio/x-mpegurl"),
        arrayOf(".m4a", "audio/mp4a-latm"),
        arrayOf(".m4b", "audio/mp4a-latm"),
        arrayOf(".m4p", "audio/mp4a-latm"),
        arrayOf(".m4u", "video/vnd.mpegurl"),
        arrayOf(".m4v", "video/x-m4v"),
        arrayOf(".mov", "video/quicktime"),
        arrayOf(".mp2", "audio/x-mpeg"),
        arrayOf(".mp3", "audio/x-mpeg"),
        arrayOf(".mp4", "video/mp4"),
        arrayOf(".acc", "video/mp4"),
        arrayOf(".mpc", "application/vnd.mpohun.certificate"),
        arrayOf(".mpe", "video/mpeg"),
        arrayOf(".mpeg", "video/mpeg"),
        arrayOf(".mpg", "video/mpeg"),
        arrayOf(".mp4", "video/mp4"),
        arrayOf(".mpga", "audio/mpeg"),
        arrayOf(".msg", "application/vnd.ms-outlook"),
        arrayOf(".ogg", "audio/ogg"),
        arrayOf(".pdf", "application/pdf"),
        arrayOf(".png", "image/png"),
        arrayOf(".pps", "application/vnd.ms-powerpoint"),
        arrayOf(".ppt", "application/vnd.ms-powerpoint"),
        arrayOf(
            ".pptx",
            "application/vnd.openxmlformats-officedocument.presentationml.presentation"
        ),
        arrayOf(".prop", "text/plain"),
        arrayOf(".rc", "text/plain"),
        arrayOf(".rmvb", "audio/x-pn-realaudio"),
        arrayOf(".rtf", "application/rtf"),
        arrayOf(".sh", "text/plain"),
        arrayOf(".tar", "application/x-tar"),
        arrayOf(".tgz", "application/x-compressed"),
        arrayOf(".txt", "text/plain"),
        arrayOf(".wav", "audio/x-wav"),
        arrayOf(".wma", "audio/x-ms-wma"),
        arrayOf(".wmv", "audio/x-ms-wmv"),
        arrayOf(".wps", "application/vnd.ms-works"),
        arrayOf(".xml", "text/plain"),
        arrayOf(".z", "application/x-compress"),
        arrayOf(".zip", "application/x-zip-compressed"),
        arrayOf("", "*/*")
    )

    /**
     * 根据 mine type 获取后缀
     */
    fun getSuffixByMediaType(mediaType: String?): String? {
        var suffix: String? = null
        try {
            for (i in MIME_ARRAY.indices) {
                if (TextUtils.equals(mediaType, MIME_ARRAY[i][1])) {
                    suffix = MIME_ARRAY[i][0]
                }
            }
        } catch (e: Exception) {
            suffix = null
        }
        return suffix
    }

    /**
     * 根据后缀 获取 对应的intent 类型
     *
     * @param suffix 后缀名称 可带‘.’ 或不带
     * @return
     */
    fun getMediaTypeBySuffix(suffix: String): String? {
        var suffix = suffix
        if (TextUtils.isEmpty(suffix))
            return null

        if (!suffix.startsWith(".")) {
            suffix = ".$suffix"
        }

        try {
            var type: String? = null
            for (i in MIME_ARRAY.indices) {
                if (suffix == MIME_ARRAY[i][0]) {
                    type = MIME_ARRAY[i][1]
                }
            }
            return type

        } catch (e: Exception) {

        }

        return null
    }


    /**
     * 通知多媒体扫描目录或者文件，支持递归 目录
     */
    fun scanFile(
        context: Context,
        paths: Array<String>,
        isLoop: Boolean = false,
        callback: ((path: String?, uri: Uri?, isLast: Boolean) -> Unit)? = null
    ) {

        if (paths.size == 1 && File(paths[0]).isFile) {
            MediaScannerConnection.scanFile(
                context, paths
                , null
            ) { path, uri ->
                callback?.invoke(path, uri, true)
            }
        } else {
            SingleOrDirectorMediaScanner(context, paths, isLoop, callback)
        }
    }
}

/**
 * 多路径 通知扫描 系统多媒体
 * 支持 递归目录
 * tips：请勿传入sd卡 根目录
 */
class SingleOrDirectorMediaScanner(
    val context: Context,
    private var paths: Array<String>,
    private val isLoop: Boolean,
    private val callback: ((path: String?, uri: Uri?, isLast: Boolean) -> Unit)? = null
) :
    MediaScannerConnection.MediaScannerConnectionClient {
    private val mediaScannerConnection: MediaScannerConnection by lazy {
        MediaScannerConnection(context, this)
    }

    private var count = 0

    init {
        mediaScannerConnection.connect()
    }

    override fun onMediaScannerConnected() {
        for (path in paths) {
            val file = File(path)
            scanFile(file)
        }
    }

    private fun scanFile(file: File) {
        if (file.isDirectory && file.listFiles().isNotEmpty()) {
            for (subFile in file.listFiles()) {
                if (subFile.isFile) {
                    mediaScannerConnection?.scanFile(subFile.absolutePath, null)
                    count += 1
                } else {
                    if (isLoop)
                        scanFile(subFile)
                }
            }
        } else {
            count += 1
            mediaScannerConnection.scanFile(file.absolutePath, null)
        }
    }

    override fun onScanCompleted(path: String?, uri: Uri?) {
        count -= 1
        val isLast = count <= 0
        callback?.invoke(path, uri, isLast)
        if (isLast) {
            mediaScannerConnection.disconnect()
        }
    }

}